﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace OverNANA
{
    public partial class DownLoadProcess : UserControl
    {
        private string BookName;
        private string BookImage;
        private System.IO.DirectoryInfo LocalDI;
        private string DownLoadDIR;
        private bool ZippedFiles;

        public DownLoadProcess()
        {
            InitializeComponent();

            lblBookName.Text = "";
            lblDirProcess.Text = "";
            lblFileProcess.Text = "";
            panRunState.BackColor = System.Drawing.Color.Green;
        }

        public string downLoadDir
        {
            get { return DownLoadDIR; }
            set { DownLoadDIR = value; }
        }

        public bool zippedFiles
        {
            get { return ZippedFiles; }
            set { ZippedFiles = value; }
        }

        public bool IsBusy
        {
            get { return backgroundWorker1.IsBusy; }
        }

        public void StartDownLoad(string ComicURL)
        {
            panRunState.BackColor = System.Drawing.Color.Red;
            backgroundWorker1.RunWorkerAsync(ComicURL);
        }

        /// <summary>
        /// 下载一部漫画(异步模式）
        /// </summary>
        /// <param name="ComicURL"></param>
        private void DownloadComicAsync(string ComicURL)
        {
            DataTable dtDirectory;
            DataTable dtFiles;

            dtDirectory = new DataTable();
            try
            {
                dtDirectory = AnalysisDirectory(ComicURL);
            }
            catch (System.Net.WebException webE1)
            {
                if (webE1.Message.IndexOf("404") >= 0)
                {
                    return;
                }
            }
            if (dtDirectory.Rows.Count <= 0)
                return;
            backgroundWorker1.ReportProgress(0, new ProcessReport("lblBookName.Text", BookName));
            backgroundWorker1.ReportProgress(0, new ProcessReport("ShowImage", BookImage));

            BookName = BookName.Replace(":", " ");
            BookName = BookName.Replace("*", " ");
            BookName = BookName.Replace("?", " ");
            BookName = BookName.Replace("<", " ");
            BookName = BookName.Replace(">", " ");
            LocalDI = new DirectoryInfo(DownLoadDIR + BookName);
            if (!LocalDI.Exists)
                LocalDI.Create();

            backgroundWorker1.ReportProgress(0, new ProcessReport("proDir.Minimum", "0"));
            backgroundWorker1.ReportProgress(0, new ProcessReport("proDir.Maximum", Convert.ToString(dtDirectory.Rows.Count * 100)));

            for (int i = 0; i < dtDirectory.Rows.Count; i++)
            {
                FileInfo ZippedFile = new FileInfo(DownLoadDIR + BookName + @"\" + Convert.ToString(dtDirectory.Rows[i].ItemArray[1]) + ".zip");

                backgroundWorker1.ReportProgress(0, new ProcessReport("lblDirProcess.Text", "目录进度(" + Convert.ToString(i + 1) + @"/" + dtDirectory.Rows.Count.ToString() + ") " + Convert.ToString(dtDirectory.Rows[i].ItemArray[1])));
                backgroundWorker1.ReportProgress(0, new ProcessReport("proDir.Value", Convert.ToString((i) * 100)));

                LocalDI = new DirectoryInfo(DownLoadDIR + BookName + @"\" + Convert.ToString(dtDirectory.Rows[i].ItemArray[1]));
                if (ZippedFile.Exists)
                    continue;
                if (!LocalDI.Exists)
                    LocalDI.Create();

                dtFiles = new DataTable();
                try
                {
                    dtFiles = AnalysisFiles(Convert.ToString(dtDirectory.Rows[i].ItemArray[0]));
                }
                catch (FormatException)
                {
                    dtFiles = AnalysisFilesEven(Convert.ToString(dtDirectory.Rows[i].ItemArray[0]));
                }
                catch (System.Net.WebException webE1)
                {
                    if (webE1.Message.IndexOf("404") >= 0)
                    {
                        continue;
                    }
                }

                for (int j = 0; j < dtFiles.Rows.Count; j++)
                {
                    int ProcessIndex = Convert.ToInt32(Convert.ToDecimal(j) / Convert.ToDecimal(dtFiles.Rows.Count) * Convert.ToDecimal(100));
                    ProcessIndex = (i * 100) + ProcessIndex;
                    backgroundWorker1.ReportProgress(0, new ProcessReport("lblFileProcess.Text", "文件进度(" + Convert.ToString(j + 1) + @"/" + dtFiles.Rows.Count.ToString() + ")"));
                    backgroundWorker1.ReportProgress(0, new ProcessReport("proDir.Value", Convert.ToString(ProcessIndex)));
                    string FileURL = Convert.ToString(dtFiles.Rows[j].ItemArray[0]);
                    string FileName = FileURL.Substring(FileURL.LastIndexOf("/") + 1);
                    FileName = LocalDI.FullName + @"\" + FileName;
                    DownloadFile(FileURL, FileName);
                }

                if (ZippedFiles)
                {
                    OverSystems.Zip.ZipClass myZip = new OverSystems.Zip.ZipClass();
                    myZip.ZipFileMain(new string[] { LocalDI.FullName + @"\", ZippedFile.FullName });
                    LocalDI.Delete(true);
                }
            }
        }

        /// <summary>
        /// 分析漫画中各分卷的页面地址
        /// </summary>
        /// <returns></returns>
        private DataTable AnalysisDirectory(string BookURL)
        {
            DataTable dtDMDirInfo = new DataTable();
            dtDMDirInfo.Columns.Add("URLS");
            dtDMDirInfo.Columns.Add("Name");

            string DirectoryURL = DownLoadCommon.GetHttp(BookURL, "", "utf-8");
            if (DirectoryURL.IndexOf("<div id=\"box-720\">") > 0)
            {
                DirectoryURL = DirectoryURL.Substring(DirectoryURL.IndexOf("<div id=\"box-720\">"));
                BookName = DirectoryURL.Substring(DirectoryURL.IndexOf("<img"));
                BookName = BookName.Substring(0, BookName.IndexOf("/>"));
                if (BookName.IndexOf("alt=") > 0)
                {
                    BookName = BookName.Substring(BookName.IndexOf("alt=") + 5);
                    BookName = BookName.Substring(0, BookName.IndexOf("\""));
                }
                else
                {
                    BookName = DirectoryURL.Substring(DirectoryURL.IndexOf("漫画名称") + 4);
                    BookName = BookName.Substring(0, BookName.IndexOf("</li>"));
                    BookName = BookName.Replace("</b>", "");
                    BookName = BookName.Replace("：", "").Trim();
                }

                BookImage = DirectoryURL.Substring(DirectoryURL.IndexOf("<img"));
                BookImage = BookImage.Substring(BookImage.IndexOf("src=") + 5);
                BookImage = BookImage.Substring(0, BookImage.IndexOf("\""));
                if (BookImage.IndexOf("http://") < 0)
                    BookImage = "http://www.nanadm.com/" + BookImage;

                DirectoryURL = DirectoryURL.Substring(DirectoryURL.IndexOf("<div id=\"zaixianmanhua\">"));
                DirectoryURL = DirectoryURL.Substring(DirectoryURL.IndexOf("<ul>"));
                DirectoryURL = DirectoryURL.Substring(0, DirectoryURL.IndexOf("</ul>") + 5);
                DirectoryURL = DirectoryURL.Replace("<ul>", "");
                DirectoryURL = DirectoryURL.Replace("</ul>", "");
                DirectoryURL = DirectoryURL.Trim();

                while (true)
                {
                    if (DirectoryURL.IndexOf("</li>") < 0)
                        break;
                    string DirectoryDetail = DirectoryURL.Substring(DirectoryURL.IndexOf("<li>"));
                    DirectoryDetail = DirectoryDetail.Substring(0, DirectoryDetail.IndexOf("</li>") + 5);
                    DirectoryDetail = DirectoryDetail.Replace("<li>", "");
                    DirectoryDetail = DirectoryDetail.Replace("</li>", "");
                    string dmURLS, dmName;
                    dmURLS = DirectoryDetail.Substring(DirectoryDetail.IndexOf("href='") + 6);
                    dmURLS = dmURLS.Substring(0, dmURLS.IndexOf("target"));
                    dmURLS = dmURLS.Replace("'", "").Trim();
                    dmURLS = "http://www.nanadm.com" + dmURLS;
                    dmName = DirectoryDetail.Substring(DirectoryDetail.IndexOf(">") + 1);
                    dmName = dmName.Substring(0, dmName.IndexOf("</a>"));
                    dmName = dmName.Replace("<strong>", "");
                    dmName = dmName.Replace("</strong>", "");
                    dmName = dmName.Replace("/", "");
                    dtDMDirInfo.Rows.Add(new object[] { dmURLS, dmName });
                    DirectoryURL = DirectoryURL.Substring(DirectoryURL.IndexOf("</li>") + 5);
                }
            }
            else
            {
                DirectoryURL = DirectoryURL.Substring(DirectoryURL.IndexOf("<div class=\"place\">"));
                BookName = DirectoryURL.Substring(0, DirectoryURL.IndexOf("</div>"));
                BookName = BookName.Substring(BookName.LastIndexOf("<a href"));
                BookName = BookName.Substring(0, BookName.IndexOf("</a>"));
                BookName = BookName.Substring(BookName.IndexOf(">") + 1).Trim();

                BookImage = DirectoryURL.Substring(DirectoryURL.IndexOf("<ul class=\"e2\">"));
                BookImage = BookImage.Substring(BookImage.IndexOf("<img"));
                BookImage = BookImage.Substring(0, BookImage.IndexOf("/>"));
                BookImage = BookImage.Substring(BookImage.IndexOf("src=") + 5);
                BookImage = BookImage.Replace("'", "").Replace("\"", "").Trim();
                if (BookImage.IndexOf("http://") < 0)
                    BookImage = "http://www.nanadm.com/" + BookImage;

                DirectoryURL = DirectoryURL.Substring(DirectoryURL.IndexOf("<div class=\"commend\">"));
                DirectoryURL = DirectoryURL.Substring(0, DirectoryURL.IndexOf("</div>"));
                while (true)
                {
                    if (DirectoryURL.IndexOf("<a href=") < 0)
                        break;
                    string DirectoryDetail = DirectoryURL.Substring(DirectoryURL.IndexOf("<a href="));
                    DirectoryDetail = DirectoryDetail.Substring(0, DirectoryDetail.IndexOf("</a>"));
                    string dmURLS, dmName;
                    dmURLS = DirectoryDetail.Substring(DirectoryDetail.IndexOf("href=") + 6);
                    dmURLS = dmURLS.Substring(0, dmURLS.IndexOf(".html") + 5);
                    dmURLS = "http://www.nanadm.com" + dmURLS;
                    dmName = DirectoryDetail.Substring(DirectoryDetail.IndexOf(">") + 1);
                    if (dmName.IndexOf("</a>") > 0)
                        dmName = dmName.Substring(0, dmName.IndexOf("</a>"));
                    dtDMDirInfo.Rows.Add(new object[] { dmURLS, dmName });
                    DirectoryURL = DirectoryURL.Substring(DirectoryURL.IndexOf("</a>") + 4);
                }

            }
            return dtDMDirInfo;
        }

        /// <summary>
        /// 分析漫画某卷中图片的存放位置
        /// </summary>
        /// <param name="URLS"></param>
        /// <returns></returns>
        private DataTable AnalysisFiles(string URLS)
        {
            DataTable dtDMFileInfo = new DataTable();
            dtDMFileInfo.Columns.Add("URLS");

            string PageHttp = DownLoadCommon.GetHttp(URLS, "", "utf-8");
            if (PageHttp.IndexOf("exit.gif") > 0)
                return dtDMFileInfo;
            if (PageHttp.IndexOf("http://www.nanadm.com/") <= 0)
                return dtDMFileInfo;

            string StartImage;
            try
            {
                StartImage = PageHttp.Substring(PageHttp.IndexOf("http://www.nanadm.com/"));
                StartImage = StartImage.Substring(0, StartImage.IndexOf("<span style=\"display: none\">"));
                StartImage = StartImage.Replace("\"", "");
                StartImage = StartImage.Replace("alt=", "");
                StartImage = StartImage.Replace("/>", "").Trim().ToLower();
            }
            catch (Exception e)
            {
                return dtDMFileInfo;
            }

            string EndURL;
            if (PageHttp.IndexOf("</select>") >= 0)
            {
                EndURL = PageHttp.Substring(0, PageHttp.IndexOf("</select>"));
                EndURL = EndURL.Substring(0, EndURL.LastIndexOf("<option"));
                EndURL = EndURL.Substring(EndURL.LastIndexOf("value=") + 7);
                EndURL = EndURL.Substring(0, EndURL.IndexOf(".html") + 5);
                EndURL = URLS.Substring(0, URLS.LastIndexOf("/") + 1) + EndURL;
            }
            else
            {
                EndURL = PageHttp.Substring(PageHttp.IndexOf("pagelist"));
                EndURL = EndURL.Substring(0, EndURL.LastIndexOf("href='view.php?"));
                EndURL = EndURL.Substring(0, EndURL.LastIndexOf("href='view.php?"));
                EndURL = EndURL.Substring(EndURL.IndexOf("href='view.php?") + 6);
                EndURL = EndURL.Substring(0, EndURL.LastIndexOf("'"));
                EndURL = "http://www.nanadm.com/plus/" + EndURL;
            }

            string EndImage;
            PageHttp = DownLoadCommon.GetHttp(EndURL, "", "utf-8");
            EndImage = PageHttp.Substring(PageHttp.IndexOf("http://www.nanadm.com/"));
            EndImage = EndImage.Substring(0, EndImage.IndexOf("/>"));
            EndImage = EndImage.Replace("alt=", "");
            EndImage = EndImage.Replace("\"", "").Trim().ToLower(); ;

            int DiffIndex = -1;//序号开始位置
            int StartIndex;//初始序号;
            int EndIndex;//终结序号;
            string PublicPath = "";//公用路径

            for (int i = 0; i < EndImage.Length; i++)
            {
                if (StartImage[i] == EndImage[i])
                {
                    PublicPath += StartImage[i];
                }
                else
                {
                    DiffIndex = i;
                    break;
                }
            }
            string FileType = ".xxx";
            if (StartImage.ToLower().IndexOf(".jpg") >= 0)
                FileType = ".jpg";
            if (StartImage.ToLower().IndexOf(".png") >= 0)
                FileType = ".png";

            string TempURL = StartImage;
            TempURL = TempURL.Replace(FileType, "");
            TempURL = TempURL.Substring(DiffIndex);
            StartIndex = Convert.ToInt32(TempURL);

            TempURL = EndImage;
            TempURL = TempURL.Replace(".jpg", "");
            TempURL = TempURL.Replace(".png", "");
            TempURL = TempURL.Substring(DiffIndex);
            EndIndex = Convert.ToInt32(TempURL);

            string NumFormat = "";
            for (int i = 0; i < TempURL.Length; i++)
            {
                NumFormat += "0";
            }

            for (int i = StartIndex; i <= EndIndex; i++)
            {
                dtDMFileInfo.Rows.Add(new object[] { PublicPath + i.ToString(NumFormat) + FileType });
            }

            return dtDMFileInfo;
        }

        /// <summary>
        /// 分析漫画某卷中图片的存放位置(逐页模式)
        /// </summary>
        /// <param name="URLS"></param>
        /// <returns></returns>
        private DataTable AnalysisFilesEven(string URLS)
        {
            DataTable dtDMFileInfo = new DataTable();
            dtDMFileInfo.Columns.Add("URLS");

            string NextURL = URLS;
            string BaseURL = URLS.Substring(0, URLS.LastIndexOf("/") + 1);

            do
            {
                string PageHttp = DownLoadCommon.GetHttp(NextURL, "", "utf-8");
                if (PageHttp.IndexOf("exit.gif") > 0)
                    break;

                string ImageURL;
                ImageURL = PageHttp.Substring(PageHttp.IndexOf("<div class=\"display_right\">"));
                ImageURL = ImageURL.Substring(ImageURL.IndexOf("src=\"http://www.nanadm.com/") + 5);
                ImageURL = ImageURL.Substring(0, ImageURL.IndexOf("\""));
                ImageURL = ImageURL.Replace("\"", "");
                ImageURL = ImageURL.Replace("/>", "").Trim().ToLower();

                dtDMFileInfo.Rows.Add(new object[] { ImageURL });

                if (PageHttp.IndexOf("<span class=view_yan2>") > 0)
                {
                    NextURL = PageHttp.Substring(PageHttp.IndexOf("<span class=view_yan2>"));
                    NextURL = NextURL.Substring(0, NextURL.IndexOf("</span>"));
                    NextURL = NextURL.Substring(NextURL.IndexOf("href=") + 6);
                    NextURL = NextURL.Substring(0, NextURL.IndexOf(">"));
                    NextURL = NextURL.Replace("'", "").Replace("\"", "");
                    if (NextURL.IndexOf("http:") <= 0)
                    {
                        NextURL = BaseURL + NextURL;
                    }
                }
                else
                {
                    NextURL = PageHttp.Substring(PageHttp.IndexOf("<ul class=\"pagelist\">"));
                    NextURL = NextURL.Substring(0, NextURL.IndexOf("</ul>"));
                    NextURL = NextURL.Substring(NextURL.LastIndexOf("<li>"));
                    NextURL = NextURL.Substring(NextURL.IndexOf("<a href=") + 9);
                    NextURL = NextURL.Substring(0, NextURL.IndexOf(">"));
                    NextURL = NextURL.Replace("'", "").Trim();
                    if (NextURL.IndexOf("http:") <= 0)
                    {
                        NextURL = BaseURL + NextURL;
                    }
                }

            } while (true);


            return dtDMFileInfo;
        }

        private void DownloadFile(string URL, string filename)
        {
            string TempFileName = filename + ".OTP";
            FileInfo myFile = new FileInfo(filename);
            FileInfo TempFile = new FileInfo(TempFileName);
            if (myFile.Exists)
                return;
            if (TempFile.Exists)
            {
                TempFile.Delete();
            }
            System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(URL);
            Myrq.Timeout = 5000;
            try
            {
                System.Net.HttpWebResponse Tmyrp;
                Tmyrp = (System.Net.HttpWebResponse)Myrq.GetResponse();
            }
            catch (System.Net.WebException e)
            {
                if (e.Message.IndexOf("404") >= 0)
                {
                    if (URL.IndexOf(".jpg") >= 0)
                    {
                        URL = URL.Replace(".jpg", ".png");
                        filename = filename.Replace(".jpg", ".png");
                    }
                    else if (URL.IndexOf(".png") >= 0)
                    {
                        URL = URL.Replace(".png", ".jpg");
                        filename = filename.Replace(".png", ".jpg");
                    }
                    myFile = new FileInfo(filename);
                    TempFileName = filename + ".OTP";
                    TempFile = new FileInfo(TempFileName);
                    try
                    {
                        Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(URL);
                        System.Net.HttpWebResponse Tmyrp = (System.Net.HttpWebResponse)Myrq.GetResponse();
                    }
                    catch
                    {
                        if (e.Message.IndexOf("404") >= 0)
                        {
                            return;
                        }
                    }
                }
                else
                    return;
            }
            System.Net.HttpWebResponse myrp;
            try
            {
                myrp = (System.Net.HttpWebResponse)Myrq.GetResponse();
            }
            catch (System.Net.WebException)
            {
                return;
            }
            long totalBytes = myrp.ContentLength;
            if (myrp.ContentLength != 0)
            {
                FileInfo ExistFile = new FileInfo(myFile.FullName);
                if (ExistFile.Exists)
                    return;
                System.IO.Stream st = myrp.GetResponseStream();
                System.IO.Stream so = new System.IO.FileStream(TempFileName, System.IO.FileMode.Create);
                long totalDownloadedByte = 0;
                byte[] by = new byte[1024];
                int osize = st.Read(by, 0, (int)by.Length);
                while (osize > 0)
                {
                    totalDownloadedByte = osize + totalDownloadedByte;
                    so.Write(by, 0, osize);
                    osize = st.Read(by, 0, (int)by.Length);
                }
                so.Close();
                st.Close();
                TempFile.MoveTo(myFile.FullName);
            }
            else
            {
                return;
            }
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            string ComicURL = Convert.ToString(e.Argument);
            DownloadComicAsync(ComicURL);
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            ProcessReport worker = (ProcessReport)e.UserState;

            switch (worker.Name)
            {
                case "proDir.Minimum":
                    proDir.Minimum = Convert.ToInt32(worker.Value);
                    break;
                case "proDir.Maximum":
                    proDir.Maximum = Convert.ToInt32(worker.Value);
                    break;
                case "proDir.Value":
                    proDir.Value = Convert.ToInt32(worker.Value);
                    break;
                case "lblDirProcess.Text":
                    lblDirProcess.Text = worker.Value;
                    break;
                case "lblFileProcess.Text":
                    lblFileProcess.Text = worker.Value;
                    break;
                case "lblBookName.Text":
                    lblBookName.Text = worker.Value;
                    break;
                case "ShowImage":
                    System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(worker.Value);
                    System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse();
                    long totalBytes = myrp.ContentLength;
                    if (myrp.ContentLength != 0)
                    {
                        System.IO.Stream st = myrp.GetResponseStream();
                        System.Drawing.Image myImage = System.Drawing.Image.FromStream(st);
                        picBookImage.Image = myImage;
                        picBookImage.Image = picBookImage.Image.GetThumbnailImage(picBookImage.Width, picBookImage.Height, null, new IntPtr());
                        st.Close();
                    }
                    break;
                default:
                    break;
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            proDir.Value = proDir.Maximum;
            panRunState.BackColor = System.Drawing.Color.Green;
        }
    }

    public struct ProcessReport
    {
        public string Name;
        public string Value;

        public ProcessReport(string name, string value)
        {
            this.Name = name;
            this.Value = value;
        }
    }
}
